home *** CD-ROM | disk | FTP | other *** search
- (*
- > Hi, I am trying to write a program the writes to Standard output,
- > and reads from Standard input from windows console (win95 dosprmpt, winnt
- > dosprmpt)... so the io can be redirected. The program must be a windows
- > program for the project to work:
- > Using the program as a script for Microsoft Internet
- > Information Server on Winnt 3.51, the web server will not execute dos based stdio
- > programs. I have tried using program script(input,output) which reports file not
- > open for write, I have added rewrite(output) which causes an error because output
- not assigned. I have assigned output to '' which outputs nothing to the
- console or the redirected file.
- >
- > If anyone understands my problem, and has an idea or
- > solution,
- > please help me. Thank you.
- >
- >
- Ok, here is the solution to your prob : you need to write a text file device
- driver. I just happen to have code. You want the StdOut things, i can't
- remember how it works =(
- p.s. the file's attached.
- (*)
-
- unit SimultIO;
- {$D-,F+,R-}
- (* Unit for simultaneous I/O.
- This will be useful for redirection - when you write to a
- file assigned to by AssignSimult, data written to it will write to
- the file AND the screen. *)
- interface
- {$F+} procedure AssignSimult(var f : text;n : string); far; {$F-}
- implementation
- uses Dos,CRT;
- var R : Registers;
- OP : Text;
- {$F+} function WriteByteToFile(FileHandle : Word;var value) : integer;far; {$F-}
- var r : registers;
- begin
- r.ah := $40;
- r.bx := FileHandle;
- r.cx := 1;
- r.ds := seg(value);
- r.dx := ofs(value);
- MsDos(R);
- if (r.flags and fcarry)<>0 then
- begin
- r.ah := $59; (* Get extended error info *)
- msdos(R);
- WriteByteToFile := r.ax; (* IOResult returns the value in InOutRes *)
- end
- else WriteByteToFile := 0;
- end;
- (*
- INT 21,40 - Write To File or Device Using Handle
- AH = 40h
- BX = file handle
- CX = number of bytes to write, a zero value truncates/extends
- the file to the current file position
- DS:DX = pointer to write buffer
-
- on return:
- AX = number of bytes written if CF not set
- = error code if CF set (see DOS ERROR CODES)
-
- - if AX is not equal to CX on return, a partial write occurred
- - this function can be used to truncate a file to the current
- file position by writing zero bytes *)
- {$F+} function StdOut(var f: textrec) : integer; far; {$F-}
- var
- p,err : integer;
- r : registers;
- begin
- if f.mode=fmclosed then
- begin
- StdOut := 103;
- exit;
- end;
- with F do
- begin
- for P := 0 to bufpos-1 do
- begin
- r.ah := $02;
- r.dl := ord(bufptr^[p]);
- msdos(R);
- end;
- BufPos:=0;
- end;
- StdOut:=0;
- end;
- {$F+} function SimultWrite(var f: textrec): integer; far; {$F-}
- var
- p,err : integer;
- begin
- if f.mode=fmclosed then
- begin
- SimultWrite := 103;
- exit;
- end;
- with F do
- begin
- for P := 0 to bufpos-1 do
- begin
- err := WriteByteToFile(Handle,BufPtr^[p]);
- if err<>0 then
- begin
- SimultWrite := Err;
- BufPos := P+1;
- exit;
- end;
- Write(OP,BufPtr^[p]);
- end;
- BufPos:=0;
- end;
- SimultWrite:=0;
- end;
- {$F+} function SimultOpen(var f: textrec): integer; far; {$F-}
- var
- P: integer;
- begin;
- case F.Mode of
- FMOutput : begin (* Rewrite *)
- if f.name[0]= #0 then
- begin
- F.InOutFunc:= @StdOut;
- F.FlushFunc:= @StdOut;
- end else begin
- r.ah := $3C;
- r.cx := $0000;
- r.ds := Seg(F.Name);
- r.dx := Ofs(F.Name);
- MsDos(R);
- if (R.flags and FCarry)<>0 then
- begin
- R.AH := $59;
- MsDos(R);
- SimultOpen := R.AX;
- exit;
- end;
- F.Handle := r.ax;
- (*
- INT 21,3C - Create File Using Handle
-
- AH = 3C
- CX = file attribute (see FILE ATTRIBUTES)
- DS:DX = pointer to ASCIIZ path name
-
- on return:
- CF = 0 if successful
- = 1 if error
- AX = files handle if successful
- = error code if failure (see DOS ERROR CODES)
-
- - if file already exists, it is truncated to zero bytes on opening
- *)
- F.InOutFunc:= @SimultWrite;
- F.FlushFunc:= @SimultWrite;
- end;
- F.BufPos:= 0;
- SimultOpen:= 0;
- end;
- FMInOut : begin (* Append *)
- f.mode := fmOutput;
- r.ah := $3d ;
- r.al := $01;
- r.cx := $0000;
- r.ds := Seg(F.Name);
- r.dx := Ofs(F.Name);
- MsDos(R);
- if (R.flags and FCarry)<>0 then
- begin
- R.AH := $59;
- MsDos(R);
- SimultOpen := R.ax;
- exit;
- end;
- F.Handle := r.ax;
- r.bx := r.ax;
- r.al := $02;
- R.ah := $42;
- r.cx := $0000;
- r.dx := $0001; (* Seek past EOF *)
- MsDos(R);
- if (r.flags and fcarry)<>0 then
- begin
- r.ah := $59;
- msdos(R);
- SimultOpen := R.AX;
- exit;
- end;
- (*
- INT 21,42 - Move File Pointer Using Handle
-
- AH = 42h
- AL = origin of move:
- 00 = beginning of file plus offset (SEEK_SET)
- 01 = current location plus offset (SEEK_CUR)
- 02 = end of file plus offset (SEEK_END)
- BX = file handle
- CX = high order word of number of bytes to move
- DX = low order word of number of bytes to move
-
- on return:
- AX = error code if CF set (see DOS ERROR CODES)
- DX:AX = new pointer location if CF not set
-
- - seeks to specified location in file
- INT 21, - Open File Using Handle
- AH =
- AL = open access mode
- 00 read only
- 01 write only
- 02 read/write
- DS:DX = pointer to an ASCIIZ file name
- =
-
- on return:
- AX = file handle if CF not set
- = error code if CF set (see DOS ERROR CODES)
- Access modes in AL:
-
- =B37=B36=B35=B34=B33=B32=B31=B30=B3 AL
- =B3 =B3 =B3 =B3 =B3 =C0=C4=C1=C4=C1=C4=C4=C4=C4 read/write/updat=
- e access mode
- =B3 =B3 =B3 =B3 =C0=C4=C4=C4=C4=C4=C4=C4=C4=C4 reserved, always =
- 0
- =B3 =C0=C4=C1=C4=C1=C4=C4=C4=C4=C4=C4=C4=C4=C4=C4 sharing mode (=
- see below) (DOS 3.1+)
- =C0=C4=C4=C4=C4=C4=C4=C4=C4=C4=C4=C4=C4=C4=C4=C4 1 = private, =
- 0 = inheritable (DOS 3.1+)
- =0D
- Sharing mode bits (DOS 3.1+): Access mode bits:
- 654 210
- 000 compatibility mode (exclusive) 000 read access
- 001 deny others read/write access 001 write access
- 010 deny others write access 010 read/write access
- 011 deny others read access
- 100 full access permitted to all
- *)
- F.InOutFunc := @SimultWrite;
- F.FlushFunc := @SimultWrite;
- F.BufPos:= 0;
- SimultOpen:= 0;
- end;
- else
- SimultOpen := 12; (* Invalid file access code - you can only Rewrite=
- or Append this *)
- end;
- end;
-
- {$F+}function SimultClose(var F: textrec): integer; far; {$F-}
- var
- P: integer;
- begin;
- if f.mode= fmclosed then
- begin
- SimultClose := 103;
- exit;
- end;
- (*
- INT 21,3E - Close File Using Handle
-
- AH = 3E
- BX = file handle to close
-
- on return:
- AX = error code if CF set (see DOS ERROR CODES)
-
- - if file is opened for update, file time and date stamp
- as well as file size are updated in the directory
- - handle is freed
- =0D
- *)
- r.ah := $3E;
- r.bx := f.handle;
- MsDos(R);
- if (R.flags and fcarry)<>0 then
- begin
- r.ah := $59;
- MsDos(R);
- SimultClose := R.AX;
- exit;
- end;
- F.Mode := FMClosed;
- SimultClose:= 0;
- end;
-
- {$F+} procedure AssignSimult(var f : text;n : string); {$F-}
- begin
- with textrec(f) do begin
- Mode := fmClosed;
- Handle := $FFFF;
- Bufsize := SizeOf(Buffer);
- Bufpos := 0;
- Bufptr := @Buffer;
- OpenFunc := @SimultOpen;
- CloseFunc:= @SimultClose;
- if n[0]>#79 then n[0] := #79; (* Truncate the name down to 79 chars=
- *)
- Move(N[1],Name[0],79);
- Name[Length(N)] := #0; (* Name is null-terminated *)
- end;
- end;
- begin
- AssignCRT(OP);
- Rewrite(OP);
- end.